package com.java.simple.study.juc.p3;

import com.java.simple.study.tool.Sleeper;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

import java.util.Vector;
import java.util.concurrent.locks.LockSupport;

/**
 * @author zhoujl
 * @date 2022/5/8 14:17
 * @desc
 */
@Slf4j(topic = "c.D")
public class TestBiased {

    public static void main(String[] args) throws InterruptedException {
        //testDelay();
        //testForbidDelay();
        //testLockObjectHeader();
        //testThreadLock();
        //testWaitNotify();
        //testReBiased();
        batchReset();
    }

    static Thread t1, t2, t3;

    public static void batchReset() throws InterruptedException {
        Vector<Dog> list = new Vector<>();
        int loopNumber = 39;
        t1 = new Thread(() -> {
            for (int i = 0; i < loopNumber; i++) {
                Dog d = new Dog();
                list.add(d);
                synchronized (d) {
                    log.debug(i + "");
                    log.debug(ClassLayout.parseInstance(d).toPrintable());
                }
            }
            LockSupport.unpark(t2);
        }, "t1");

        t2 = new Thread(() -> {
            LockSupport.park();
            log.debug("---------------------------");
            for (int i = 0; i < loopNumber; i++) {
                Dog d = list.get(i);
                log.debug(i + "");
                log.debug(ClassLayout.parseInstance(d).toPrintable());
                synchronized (d) {
                    log.debug(ClassLayout.parseInstance(d).toPrintable());
                }
                log.debug(ClassLayout.parseInstance(d).toPrintable());
            }
            LockSupport.unpark(t3);
        }, "t2");

        t3 = new Thread(() -> {
            LockSupport.park();
            log.debug("---------------------------");
            for (int i = 0; i < loopNumber; i++) {
                Dog d = list.get(i);
                log.debug(i + "");
                log.debug(ClassLayout.parseInstance(d).toPrintable());
                synchronized (d) {
                    log.debug(ClassLayout.parseInstance(d).toPrintable());
                }
                log.debug(ClassLayout.parseInstance(d).toPrintable());
            }
        }, "t3");

        t1.start();
        t2.start();
        t3.start();
        t3.join();
        log.debug(ClassLayout.parseInstance(new Dog()).toPrintable());
    }

    public static void testReBiased() {
        Vector<Dog> list = new Vector<>();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                Dog dog = new Dog();
                list.add(dog);
                synchronized (dog) {
                    log.debug(i + "");
                    // 此时都会偏向t1线程
                    log.debug(ClassLayout.parseInstance(dog).toPrintable());
                }
            }
            synchronized (list) {
                list.notify();
            }
        }, "t1");
        t1.start();

        Thread t2 = new Thread(() -> {
            synchronized (list) {
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.debug("----------------------------------");
            for (int i = 0; i < 30; i++) {
                if (i == 19) {
                    log.debug("注意了！！！！到20了");
                }
                Dog dog = list.get(i);
                log.debug(i + "");
                //还是偏向t1的 （当到达阈值时偏向t2）
                log.debug(ClassLayout.parseInstance(dog).toPrintable());
                synchronized (dog) {
                    // 有线程竞争->轻量级锁  （当到达阈值时偏向t2的偏向锁）
                    log.debug(ClassLayout.parseInstance(dog).toPrintable());
                }
                // 正常无锁状态  （当到达阈值时偏向t2的偏向锁）
                log.debug(ClassLayout.parseInstance(dog).toPrintable());
            }
        }, "t2");
        t2.start();

    }


    public static void testWaitNotify() {
        Dog dog = new Dog();
        new Thread(() -> {
            // 偏向锁 101
            log.debug(ClassLayout.parseInstance(dog).toPrintable());
            synchronized (dog) {
                // 偏向锁 101
                log.debug(ClassLayout.parseInstance(dog).toPrintable());
                try {
                    // 等待t2线程唤醒
                    dog.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //变成了 重量级锁010  （wait notify 自动会变成重量级锁）
                log.debug(ClassLayout.parseInstance(dog).toPrintable());
            }
        }, "t1").start();


        new Thread(() -> {
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (dog) {
                log.debug("notify");
                dog.notify();
            }
        }, "t2").start();

    }

    public static void testThreadLock() {
        Dog dog = new Dog();
        Thread t1 = new Thread(() -> {
            synchronized (dog) {
                log.debug(ClassLayout.parseInstance(dog).toPrintable());
            }
            synchronized (TestBiased.class) {
                TestBiased.class.notify();
            }
        }, "t1");
        t1.start();

        Thread t2 = new Thread(() -> {
            synchronized (TestBiased.class) {
                try {
                    TestBiased.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.debug(ClassLayout.parseInstance(dog).toPrintable());
            synchronized (dog) {
                log.debug(ClassLayout.parseInstance(dog).toPrintable());
            }
            log.debug(ClassLayout.parseInstance(dog).toPrintable());
        }, "t2");
        t2.start();
    }


    public static void testLockObjectHeader() {
        Dog dog = new Dog();
        dog.hashCode();
        ClassLayout classLayout = ClassLayout.parseInstance(dog);
        new Thread(() -> {
            log.debug("synchronized 前");
            System.out.println(classLayout.toPrintable());
            synchronized (dog) {
                log.debug("synchronized 中");
                System.out.println(classLayout.toPrintable());
            }
            log.debug("synchronized 后");
            System.out.println(classLayout.toPrintable());
        }, "t1").start();
    }


    public static void testForbidDelay() {
        // jvm参数 -XX:BiasedLockingStartupDelay=0 延迟设为0秒不延迟  默认4秒
        // -XX:-UseBiasedLocking 关闭偏向锁
        System.out.println(ClassLayout.parseInstance(new Dog()).toPrintable());
        System.out.println(ClassLayout.parseInstance(new Dog()).toPrintable());
    }

    public static void testDelay() {
        //00000001
        System.out.println(ClassLayout.parseInstance(new Dog()).toPrintable());
        // 延迟几秒后 对象才会编程偏向锁
        Sleeper.sleep(4);
        //00000101
        System.out.println(ClassLayout.parseInstance(new Dog()).toPrintable());
    }

}

class Dog {
}
